<template>
  <form>
    x: <input v-model="x" /> y: <input v-model="y" />
    <button type="button" @click="submit">预测</button>
  </form>
</template>

<script>
import { reactive, toRefs } from "vue";
import * as tf from "@tensorflow/tfjs";
import * as tfvis from "@tensorflow/tfjs-vis";
import { getData } from "./data";

export default {
  setup: async () => {
    const data = getData(400);

    tfvis.render.scatterplot(
      { name: "逻辑回归训练数据" },
      {
        values: [
          data.filter((p) => p.label === 1),
          data.filter((p) => p.label === 0),
        ],
      }
    );

    const model = tf.sequential();
    model.add(
      tf.layers.dense({
        units: 1,
        inputShape: [2],
        activation: "sigmoid",
      })
    );
    model.compile({ loss: tf.losses.logLoss, optimizer: tf.train.adam(0.1) });

    const form = reactive({
      x: "",
      y: "",
    });

    const inputs = tf.tensor(data.map((p) => [p.x, p.y]));
    const labels = tf.tensor(data.map((p) => p.label));

    await model.fit(inputs, labels, {
      batchSize: 40,
      epochs: 50,
      callbacks: tfvis.show.fitCallbacks({ name: "训练过程" }, ["loss"]),
    });

    function submit() {
      const pred = model.predict(tf.tensor([[form.x * 1, form.y * 1]]));
      alert(`预测结果：${pred.dataSync()[0]}`);
    }

    return {
      ...toRefs(form),
      submit,
    };
  },
};
</script>